import time
import random
import requests
from xml.etree import ElementTree as ET

from applet.models import RxMember

APP_ID = "wx3588c79e5588d6bd"
APP_SECRET = "cac006c758deea10927014fc7b290445"
MCH_ID = "1650718617"


# open_id = "oXyvU5FDSM5CX4RdVZ1hw0PSZUzs"


# 进行加密
def md5(string):
    """md5加密"""
    import hashlib
    m = hashlib.md5()
    m.update(string.encode('utf-8'))
    return m.hexdigest()


def get_access_token():
    url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}'.format(APP_ID,
                                                                                                             APP_SECRET)
    res = requests.get(url).json()
    access_token = res.get('access_token', None)
    if access_token is None:
        print("not acquired")
    else:
        print("access_token", access_token)


def generate_md5(string_2_encrypt):
    md5 = hashlib.md5()
    md5.update(string_2_encrypt.encode('utf-8'))
    return md5.hexdigest()


def generate_nonce_str(length=32):
    return ''.join(random.choices(string.ascii_letters + string.digits, k=length))


def generate_sign(data):
    key = 'your key'
    string_a = '&'.join(["{0}={1}".format(k, data.get(k, '')) for k in sorted(data)])
    string_sign_temp = '{0}&key={1}'.format(string_a, key)
    sign = generate_md5(string_sign_temp).upper()
    return sign


def pre_order():
    body = 'your body'
    nonce_str = generate_nonce_str()
    notify_url = 'your notify url'
    out_trade_no = '1111111111111111'
    spbill_create_ip = '1111'
    total_fee = '3'
    trade_type = 'JSAPI'
    openid = 'sdfewfewewfer'

    data = {
        'appid': APP_ID,
        'body': body,
        'mch_id': MCH_ID,
        'nonce_str': nonce_str,
        'notify_url': notify_url,
        'out_trade_no': out_trade_no,
        'spbill_create_ip': spbill_create_ip,
        'total_fee': total_fee,
        'trade_type': trade_type,
        'openid': openid
    }

    data['sign'] = generate_sign(data)

    url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'
    res = requests.post(url, data=str(data).encode('utf-8')).text
    print(res)


class WxPay:
    def pay(self, **kwargs):
        """
        预支付
        """
        open_id = kwargs.get("open_id")
        member_type = kwargs.get("member_type")
        member = RxMember.objects.get(member_name=member_type)
        order_random_string = str(int(time.time()))

        info = {
            "appid": APP_ID,
            "mch_id": MCH_ID,
            "device_info": "ymq-text",
            "nonce_str": "".join([chr(random.randint(65, 90)) for _ in range(12)]),
            "sign_type": "MD5",
            "body": "支付测试",
            "detail": member.member_name,
            "attach": "河南彭于晏",
            "out_trade_no": order_random_string,
            "total_fee": int(member.price * 100),  # 总金额
            # 终端IP(用户ip) F
            "spbill_create_ip": "192.168.8.3",
            # # 支付成功之后，微信异步通知(post) T
            # "notify_url": "http://121.36.196.239:1000/applet/payNotify",
            "notify_url": "http://mini.unicorn-go.com:1000/applet/payNotify",
            # 交易类型 T
            "trade_type": "JSAPI",
            # 用户标识(trade_type=JSAPI，此参数必传)
            'openid': open_id
        }
        # 1.1 签名
        #       对字典中的key按照ASCII码从小到大排序
        #       将排完序的值拼接 stringA = appid=wx55cca0b94f723dc7&mch_id=1526049051
        #       让stringA和key拼接：stringSignTemp = stringA+"&key=192006250b4c09247ec02edce69f6a2d" key为商户平台设置的密钥key
        #       MD5(stringSignTemp)
        #       将密文转换为大写
        #       得到签名 sign
        #       把签名再添加到info中    info['sign'] = sign值

        # 商户密钥key
        pay_key = "ialn3sltm2qwxd2njxx1v2ohb42lfogv"
        #
        temp = "&".join(["{0}={1}".format(k, info[k]) for k in sorted(info)] + ["{0}={1}".format("key", pay_key, ), ])
        sign = md5(temp).upper()
        info['sign'] = sign
        # 1.2 向 https://api.mch.weixin.qq.com/pay/unifiedorder 发请求 (json转换为xml)

        xml_string = "<xml>{0}</xml>".format("".join(["<{0}>{1}</{0}>".format(k, v) for k, v in info.items()]))
        prepay = requests.post('https://api.mch.weixin.qq.com/pay/unifiedorder', data=xml_string.encode('utf-8'))
        # 1.3 从结果xml中提取 prepay_id

        root = ET.XML(prepay.content.decode('utf-8'))
        prepay_dict = {child.tag: child.text for child in root}
        print("prepay_dict", prepay_dict)
        prepay_id = prepay_dict['prepay_id']

        print("prepay_id", prepay_id)
        # ####################### 2.再次签名 #######################
        info_dict = {
            # 小程序的appid
            "appId": APP_ID,
            "timeStamp": str(int(time.time())),  # 时间戳从1970年1月1日00:00:00至今的秒数,即当前的时间
            "nonceStr": "".join([chr(random.randint(65, 90)) for _ in range(12)]),  # 随机字符串，长度为32个字符以下。
            "package": 'prepay_id={0}'.format(prepay_id),  # 统一下单接口返回的 prepay_id 参数值，提交格式如：prepay_id=*
            "signType": "MD5",  # 签名类型，默认为MD5，支持HMAC-SHA256和MD5。注意此处需与统一下单的签名类型一致
        }
        temp = "&".join(
            ["{0}={1}".format(k, info_dict[k]) for k in sorted(info_dict)] + ["{0}={1}".format("key", pay_key, ), ])
        sign2 = md5(temp).upper()
        info_dict['paySign'] = sign2

        print("info_dict", info_dict)
        return (prepay_dict, prepay_id, info_dict, info)

    def get_open_id(self, code):
        """
        获取open_id
        """
        info = {
            "appid": APP_ID,
            "secret": APP_SECRET,
            "js_code": code,
            "grant_type": "authorization_code"
        }
        response = requests.get(url='https://api.weixin.qq.com/sns/jscode2session', params=info)

        # oXyvU5FDSM5CX4RdVZ1hw0PSZUzs
        result = response.json()
        if "openid" in result.keys():
            openid = result['openid']
            return (True, openid)
        else:
            return (False, result.get("errmsg"))
